unit Functions;

interface

uses
  Database, VarGrabber,
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons;

type
  TFormFunctions = class(TForm)
    BtnOK: TBitBtn;
    BtnCancel: TBitBtn;
    List1: TListBox;
    Memo: TMemo;
    LabelFun: TLabel;
    EditCopy: TEdit;
    LabelFunction: TLabel;
    Edit1: TEdit;
    LabelOperator: TLabel;
    LabelR: TLabel;
    Edit2: TEdit;
    BtnVar1: TBitBtn;
    BtnVar2: TBitBtn;
    procedure FormCreate(Sender: TObject);
    procedure BtnCancelClick(Sender: TObject);
    procedure BtnOKClick(Sender: TObject);
    procedure List1KeyPress(Sender: TObject; var Key: Char);
    procedure List1Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure BtnVar1Click(Sender: TObject);
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
  private
    { Private declarations }
    procedure UpdateDescription;
  public
    { Public declarations }
    po: integer;
    procedure Setup(fun: integer; str: string);
  end;

var
  FormFunctions: TFormFunctions;
  desc: TStringList;
  senttext: string;

implementation

{$R *.DFM}

procedure TFormFunctions.FormCreate(Sender: TObject);
begin
  po:=0;
  senttext:='';
  List1.itemindex:=1;
  List1.itemindex:=0;
  desc:=TStringList.create;
end;

procedure TFormFunctions.Setup(fun: integer; str: string);
begin
  List1.itemindex:=fun;
  senttext:=str;
  UpdateDescription;
end;

procedure TFormFunctions.FormDestroy(Sender: TObject);
begin
  desc.free;
end;

procedure TFormFunctions.BtnCancelClick(Sender: TObject);
begin
  close;
end;

procedure TFormFunctions.List1KeyPress(Sender: TObject; var Key: Char);
begin
  if key = #13 then begin
    key:=#0;
    BtnOK.click;
  end
  else UpdateDescription;
end;

procedure TFormFunctions.BtnOKClick(Sender: TObject);
var
  i, p: integer;
  work, m: string;
begin
  i:=List1.itemindex;
  if i < 0 then exit;
  work:=List1.items[i];
  work:=copy(work,1,length(work)-1);
  Datawell.lastfunction:=List1.itemindex;
  if (List1.itemindex < 13) and (List1.itemindex <> 5) and (List1.itemindex <> 6) then begin
    case List1.itemindex of
      0: m:='=';
      1: m:='+=';
      2: m:='-=';
      3: m:='*=';
      4: m:='/=';
      5: m:='++';
      6: m:='--';
      7: m:='+';
      8: m:='-';
      9: m:='*';
     10: m:='/';
     11: m:='%';
     12: m:='^';
    end;
    if (Edit1.text <> '') or (Edit2.text <> '') then begin
      work:=copy(work,1,length(work)-1);
      if (List1.itemindex > 0) and (List1.itemindex < 7) then
        work:=copy(work,1,length(work)-1);
      EditCopy.text:=work+Edit1.text+m+Edit2.text+')';
    end
    else begin
      p:=pos(',',senttext);
      if p > 0 then
        EditCopy.text:=work+copy(senttext,1,p-1)+m+copy(senttext,p+1,9999)+')'
      else EditCopy.text:=work+senttext+')';
    end;
  end
  else if (List1.itemindex = 5) or (List1.itemindex = 6) then begin
    if Edit1.text = '' then Edit1.text:=senttext;
    work:=copy(work,1,length(work)-2);
    case List1.itemindex of
      5: m:='++';
      6: m:='--';
    end;
    EditCopy.text:=work+Edit1.text+m+')';
  end
  else if List1.itemindex < 27 then begin
    if Edit1.text = '' then Edit1.text:=senttext;
    EditCopy.text:=work+Edit1.text+')';
  end
  else EditCopy.text:=work+senttext+')';
  EditCopy.selectall;
  EditCopy.copytoclipboard;
  po:=length(EditCopy.text);
  close;
end;

procedure TFormFunctions.List1Click(Sender: TObject);
begin
  UpdateDescription;
end;

procedure TFormFunctions.UpdateDescription;
begin
  //Hide controls
  LabelFunction.hide;
  Edit1.hide;
  BtnVar1.hide;
  LabelOperator.hide;
  Edit2.hide;
  BtnVar2.hide;
  LabelR.hide;
  LabelR.left:=471;
  with Memo.lines do begin
    clear;
    if List1.itemindex < 13 then begin
      //Show controls
      LabelFunction.show;
      Edit1.show;
      BtnVar1.show;
      LabelOperator.show;
      Edit2.show;
      BtnVar2.show;
      LabelR.show;
      LabelR.left:=471;
      if (List1.itemindex = 5) or (List1.itemindex = 6) then begin
        Edit2.hide;
        BtnVar2.hide;
        LabelR.left:=347;
      end;
      //Position controls
      if List1.itemindex < 7 then LabelFunction.caption:='set('
      else LabelFunction.caption:='math(';
      case List1.itemindex of
        0: LabelOperator.caption:='=';
        1: LabelOperator.caption:='+ =';
        2: LabelOperator.caption:='- =';
        3: LabelOperator.caption:='* =';
        4: LabelOperator.caption:='/ =';
        5: LabelOperator.caption:='+ +';
        6: LabelOperator.caption:='- -';
        7: LabelOperator.caption:='+';
        8: LabelOperator.caption:='-';
        9: LabelOperator.caption:='*';
       10: LabelOperator.caption:='/';
       11: LabelOperator.caption:='%';
       12: LabelOperator.caption:='^';
      end;
    end
    else if List1.itemindex < 27 then begin
      //Show controls
      LabelFunction.show;
      Edit1.show;
      BtnVar1.show;
      LabelR.show;
      //Position controls
      LabelFunction.caption:=copy(List1.items[List1.itemindex],1,length(List1.items[List1.itemindex])-1);
      LabelR.left:=327;
    end;
    case List1.itemindex of
   0..6: begin
           LabelFun.caption:='set(operand-operator-expression)';
           add('Used to assign values to variables and evaluators');
           add('');
           add('Available Operators:');
           add('= : Assigns the value of the expresstion to the operand');
           add('+= : Adds expression to the operand');
           add('-= : Subtracts expression from operand');
           add('*= : Multiples operand by expression');
           add('/= : Divides operand by expression');
           add('++ : Increments operand by 1');
           add('-- : Decrements operand by 1');
           add('');
           add('Examples:');
           add('set(@BB=5) sets 5 to the variable @BB');
           add('set(@BB+=10) adds 10 to the value in variable @BB');
           add('set(@HP=67) sets the HP value to 67');
           add('set(@SOUND=c:/sounds/bach.midi) tries to play the music file');
         end;
   7..12: begin
           LabelFun.caption:='math(integer1-operator-integer2)';
           add('Used to execute arithmetic operations on two integers');
           add('');
           add('Available Arithmetic Operators:');
           add('+ : addition');
           add('- : subtraction');
           add('* : multiplication');
           add('/ : division');
           add('% : modulus (returns any remainder of a division operation)');
           add('^ : raise to a power');
           add('');
           add('Examples:');
           add('math(10+3) returns 13');
           add('math(10-3) returns 7');
           add('math(10*3) returns 30');
           add('math(10/3) returns 3 (any remainder is truncated)');
           add('math(10%3) returns 1 (the remainder from 10/3)');
           add('math(10^3) returns 1000 (10 to the 3rd power)');
         end;
     13: begin
           LabelFun.caption:='sqrt(integer)';
           add('Returns the square root of an integer (truncating any remainder)');
           add('');
           add('Examples:');
           add('sqrt(16) returns 4');
           add('sqrt(64) returns 8');
           add('sqrt(72) returns 8 (remainder is truncated)');
         end;
     14: begin
           LabelFun.caption:='random(integer)';
           add('Returns a random number between 0 and the integer supplied minus 1 inclusive');
           add('');
           add('Examples:');
           add('random(2) returns a random number from 0 to 1 (0 or 1)');
           add('random(5) returns a random number from 0 to 4 (0, 1, 2, 3 or 4)');
           add('random(999) returns a random number from 0-998');
         end;
     15: begin
           LabelFun.caption:='abs(integer)';
           add('Returns the absolute (positive) value of an integer');
           add('');
           add('Examples:');
           add('abs(-22) returns 22');
           add('abs(65) returns 65');
           add('abs(0) returns 0');
         end;
     16: begin
           LabelFun.caption:='sum(integer1,integer2,..,integerN)';
           add('Sums a list of integers');
           add('');
           add('Examples:');
           add('sum(1,2,3) returns 6');
           add('sum(10,20,30) returns 60');
           add('sum(50,-100,25) returns -25');
         end;
     17: begin
           LabelFun.caption:='avg(integer1,integer2,..,integerN)';
           add('Returns the average of a list of integers (truncating any remainder)');
           add('');
           add('Examples:');
           add('avg(1,2,3) returns 2');
           add('avg(10,20,30) returns 20');
           add('avg(1,2,3,4) returns 2  (2.5 gets truncated to 2)');
         end;
     18: begin
           LabelFun.caption:='cap(string)';
           add('Capitalizes the first character of a string (non-alphabetic '+
             'characters are ignored)');
           add('');
           add('Examples:');
           add('cap(abcdef) returns Abcdef');
           add('cap(bob) returns Bob');
           add('cap(BOB) returns BOB');
           add('cap(123abc) returns 123abc');
         end;
     19: begin
           LabelFun.caption:='CAP(string)';
           add('Capitalizes all alphabetic characters in a string');
           add('');
           add('Examples:');
           add('CAP(abcdef) returns ABCDEF');
           add('CAP(bob) returns BOB');
           add('CAP(BOB) returns BOB');
           add('CAP(123abc) returns 123ABC');
         end;
     20: begin
           LabelFun.caption:='lc(string)';
           add('Makes every alphabetic character in a string lower-case');
           add('');
           add('Examples:');
           add('lc(ABCDEF) returns abcdef');
           add('lc(abCDeF) returns abcdef');
           add('lc(Bob) returns bob');
           add('lc(123AbC) returns 123abc');
         end;
     21: begin
           LabelFun.caption:='dl(string)';
           add('Deletes the leading (first) character of a string');
           add('');
           add('Examples:');
           add('dl(abcdef) returns bcdef');
           add('dl(pete) returns ete');
           add('dl(Fred) returns red');
           add('dl(side-pocket) returns ide-pocket');
         end;
     22: begin
           LabelFun.caption:='dt(string)';
           add('Deletes the trailing (last) character of a string');
           add('');
           add('Examples:');
           add('dt(abcdef) returns abcde');
           add('dt(pete) returns pet');
           add('dt(Fred) returns Fre');
           add('dt(side-pocket) returns side-pocke');
         end;
     23: begin
           LabelFun.caption:='cls(string)';
           add('Clears all leading spaces from a string');
           add('');
           add('Examples:');
           add('cls(     abc) returns abc');
         end;
     24: begin
           LabelFun.caption:='cts(string)';
           add('Clears all trailing spaces from a string');
           add('');
           add('Examples:');
           add('cts(abc     ) returns abc');
         end;
     25: begin
           LabelFun.caption:='cbs(string)';
           add('Clears both leading and trailing spaces from a string');
           add('');
           add('Examples:');
           add('cbs(     abc      ) returns abc');
         end;
     26: begin
           LabelFun.caption:='length(string)';
           add('Returns the length of string (number of characters)');
           add('');
           add('Examples:');
           add('length(123abc) returns 6');
           add('length(Bob) returns 3');
           add('length(12345678) returns 8');
           add('length(give rock to john) returns 17');
         end;
     27: begin
           LabelFun.caption:='pos(substring,string)';
           add('Returns the position of a substring within a string.  '+
             'If the substring is not anywhere within the string, pos() returns 0');
           add('');
           add('Examples:');
           add('pos(f,abcdefghi) returns 6');
           add('pos(uck,I suck) returns 4');
           add('pos(duck,I suck) returns 0  (because "duck" is not in "I suck"');
         end;
     28: begin
           LabelFun.caption:='copy(string,start,length)';
           add('Used to extract a specific portion of a string starting at a '+
             'specific position within the string, a certain number of characters '+
             'in length');
           add('');
           add('Examples:');
           add('copy(abcdefg,2,3) returns bcd');
           add('copy(abcdefg,1,4) returns abcd');
           add('copy(abcdefg,2,99999) returns bcdefg');
         end;
     29: begin
           LabelFun.caption:='delete(string,start,length)';
           add('Deletes specific characters from a string starting at a '+
             'specific position within the string, a certain number of characters '+
             'in length');
           add('');
           add('Examples:');
           add('delete(abcdefg,2,3) returns aefg');
           add('delete(abcdefg,1,4) returns efg');
           add('delete(abcdefg,2,99999) returns a');
         end;
     30: begin
           LabelFun.caption:='subs(oldstring,newstring,string)';
           add('Substitutes all instances of an existing substring (within '+
             'a bigger string) with a new string');
           add('');
           add('Examples:');
           add('subs(x,a,xyz) returns ayz');
           add('subs( ,,a b      c   d  e f) returns abcdef');
           add('subs(a,1,@test) when test=aardvark returns 11rdv1rk');
         end;
     31: begin
           LabelFun.caption:='datetime(string)';
           add('Returns the current date-time, formatted according to the '+
             'parameters you choose');
           add('');
           add('Examples: (assume current date/time as: April 7th 1971 '+
             'at 10:32:00pm)');
           add('datetime(mm/dd/yy) returns 04/07/71');
           add('datetime(h:nn:ss d/m/yyyy) returns 10:32:00 4/7/1971');
           add('datetime(''Sometime in ''mmmm'' after ''ham/pm) returns ');
           add('  Sometime in April after 10pm');
         end;
     32: begin
           LabelFun.caption:='R(string1,string2,..,stringN)';
           add('Random Case Expression');
           add('Returns a random member of a supplied list of strings');
           add('');
           add('Examples:');
           add('R(grin,smile,dance)');
           add('  Returns either grin, smile or dance');
           add('R(1,2,3,4,fish,6,7)');
           add('  Returns either 1, 2, 3, 4, fish, 6 or 7');
         end;
     33: begin
           LabelFun.caption:='@(string:string1=value1,string2=value2,..,stringN=valueN)';
           add('Case Expression');
           add('Takes a string (or variable) and compares it against '+
             'a supplied list of strings.  If a match occurs, the value '+
             'associated with the matched string is returned.  If no '+
             'match exists, the last value in the list is returned.');
           add('');
           add('Examples:');
           add('@(Death:Good=80,Bruises=40,Death=10)');
           add('  The string being compared is "Death"');
           add('  There is a matching string in the list, and the');
           add('  value associated with it is 10, thus, 10 is returned');
           add('@(@status:Good=80,Bruises=40,Death=10)');
           add('  The string being compared is the variable @status');
           add('  When @status=Good, the function returns 80');
           add('  When @status=Bruises, the function returns 40');
           add('  When @status=Death, the function returns 10');
           add('@(@response:10=I''m angry,30=I''m ok,50=I''m great,xxx=No clue)');
           add('  When @response=10, "I''m angry" is returned');
           add('  When @response=30, "I''m ok" is returned');
           add('  When @response=50, "I''m great" is returned');
           add('  When @response is anything other than 10, 30 or 50,');
           add('    the function returns "No clue"');
         end;
     34: begin
           LabelFun.caption:='and(logicalvalue1,logicalvalue2)';
           add('Logical Function and(): used in if/then/else statements');
           add('Returns the logical "and" of two logical comparison values');
           add('');
           add('Possible Logical Values:');
           add('A <> B : A is not equal to B');
           add('A >= B : A is greater than or equal to B');
           add('A <= B : A is less than or equal to B');
           add('A > B : A is greater than B');
           add('A < B : A is less than B');
           add('A = B : A is equal to B');
           add('0 : always false');
           add('1 : always true');
           add('');
           add('A and B can be constant values (integer or string) or they can '+
             'be other functions (even other logic functions)');
           add('');
           add('Examples:');
           add('and(1=1,0=0)');
           add('  Returns true because both conditions are true');
           add('and(1=0,0=0)');
           add('  Returns false because at least one condition is');
           add('  false (the first one)');
         end;
     35: begin
           LabelFun.caption:='or(logicalvalue1,logicalvalue2)';
           add('Logical Function or(): used in if/then/else statements');
           add('Returns the logical "or" of two logical values');
           add('');
           add('Possible Logical Values:');
           add('A <> B : A is not equal to B');
           add('A >= B : A is greater than or equal to B');
           add('A <= B : A is less than or equal to B');
           add('A > B : A is greater than B');
           add('A < B : A is less than B');
           add('A = B : A is equal to B');
           add('0 : always false');
           add('1 : always true');
           add('');
           add('A and B can be constant values (integer or string) or they can '+
             'be other functions (even other logic functions)');
           add('');
           add('Examples:');
           add('or(1=0,0=0)');
           add('  Returns true because at least one condition is');
           add('  true (the second one)');
           add('or(1=0,0=1)');
           add('  Returns false because both conditions are false');
         end;
     36: begin
           LabelFun.caption:='not(logicalvalue)';
           add('Logical Function not(): used in if/then/else statements');
           add('Returns the logical reverse of a logical value');
           add('');
           add('Possible Logical Values:');
           add('A <> B : A is not equal to B');
           add('A >= B : A is greater than or equal to B');
           add('A <= B : A is less than or equal to B');
           add('A > B : A is greater than B');
           add('A < B : A is less than B');
           add('A = B : A is equal to B');
           add('0 : always false');
           add('1 : always true');
           add('');
           add('A and B can be constant values (integer or string) or they can '+
             'be other functions (even other logic functions)');
           add('');
           add('Examples:');
           add('not(1=1)');
           add('  Returns false, because the not() function reverses ');
           add('  what would normally be a true statement');
           add('not(1>1)');
           add('  Returns true, because the not() function reverses ');
           add('  what would normally be a false statement');
         end;
     37: begin
           LabelFun.caption:='ticker(ticker ID)';
           add('Function ticker():');
           add('Returns the number of seconds remaining on an active ticker');
           add('');
           add('If the ticker ID is invalid, or tickers are disabled, it will return an error message');
         end;
    end;
  end;
end;

procedure TFormFunctions.BtnVar1Click(Sender: TObject);
var
  form: TFormVarGrab;
  grab: string;
begin
  form:=TFormVarGrab.create(self);
  form.setup;
  if (LabelFunction.caption <> 'set(') or (TComponent(sender).tag <> 1) then begin
    //Disable Evaluators
    form.ListEvaluators.enabled:=false;
    form.ListEvaluators.color:=clsilver;
    form.Label4.enabled:=false;
    form.Label4a.enabled:=false;
    form.BtnOK3.enabled:=false;
  end;
  if (LabelFunction.caption = 'set(') and (TComponent(sender).tag = 1) then begin
    //Disable References
    form.ListReference.enabled:=false;
    form.ListReference.color:=clsilver;
    form.Label5.enabled:=false;
    form.Label5a.enabled:=false;
    form.BtnOK4.enabled:=false;
  end;
  form.showmodal;
  grab:=form.grab;
  form.free;
  if grab = '' then exit;
  if TComponent(sender).tag = 1 then begin
    Edit1.text:=grab;
    if Edit2.visible then Edit2.setfocus;
  end
  else begin
    Edit2.text:=grab;
    BtnOK.setfocus;
  end;
end;

procedure TFormFunctions.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if key = #13 then begin
    key:=#0;
    if TComponent(sender).tag = 1 then BtnVar1.click
    else BtnVar2.click;
  end;
end;

end.
